/**
 * PANDA 3D SOFTWARE
 * Copyright (c) Carnegie Mellon University.  All rights reserved.
 *
 * All use of this software is subject to the terms of the revised BSD
 * license.  You should have received a copy of this license along
 * with this source code in a file named "LICENSE."
 *
 * @file encryptStream.h
 * @author drose
 * @date 2004-09-01
 */

#ifndef ENCRYPTSTREAM_H
#define ENCRYPTSTREAM_H

#include "dtoolbase.h"

// This module is not compiled if OpenSSL is not available.
#ifdef HAVE_OPENSSL

#include "encryptStreamBuf.h"

/**
 * An input stream object that uses OpenSSL to decrypt the input from another
 * source stream on-the-fly.
 *
 * Attach an IDecryptStream to an existing istream that provides encrypted
 * data, as generated by an OEncryptStream, and read the corresponding
 * unencrypted data from the IDecryptStream.
 *
 * Seeking is not supported.
 */
class EXPCL_DTOOL_PRC IDecryptStream : public std::istream {
PUBLISHED:
  INLINE IDecryptStream();
  INLINE explicit IDecryptStream(std::istream *source, bool owns_source,
                                 const std::string &password);

#if _MSC_VER >= 1800
  INLINE IDecryptStream(const IDecryptStream &copy) = delete;
#endif

  INLINE IDecryptStream &open(std::istream *source, bool owns_source,
                              const std::string &password);
  INLINE IDecryptStream &close();

  INLINE const std::string &get_algorithm() const;
  INLINE int get_key_length() const;
  INLINE int get_iteration_count() const;

  MAKE_PROPERTY(algorithm, get_algorithm);
  MAKE_PROPERTY(key_length, get_key_length);
  MAKE_PROPERTY(iteration_count, get_iteration_count);

public:
  bool read_magic(const char *magic, size_t size);

private:
  EncryptStreamBuf _buf;
};

/**
 * An input stream object that uses OpenSSL to encrypt data to another
 * destination stream on-the-fly.
 *
 * Attach an OEncryptStream to an existing ostream that will accept encrypted
 * data, and write your unencrypted source data to the OEncryptStream.
 *
 * Seeking is not supported.
 */
class EXPCL_DTOOL_PRC OEncryptStream : public std::ostream {
PUBLISHED:
  INLINE OEncryptStream();
  INLINE explicit OEncryptStream(std::ostream *dest, bool owns_dest,
                                 const std::string &password);

#if _MSC_VER >= 1800
  INLINE OEncryptStream(const OEncryptStream &copy) = delete;
#endif

  INLINE OEncryptStream &open(std::ostream *dest, bool owns_dest,
                              const std::string &password);
  INLINE OEncryptStream &close();

public:
  INLINE const std::string &get_algorithm() const;
  INLINE int get_key_length() const;
  INLINE int get_iteration_count() const;

PUBLISHED:
  INLINE void set_algorithm(const std::string &algorithm);
  INLINE void set_key_length(int key_length);
  INLINE void set_iteration_count(int iteration_count);

  MAKE_PROPERTY(algorithm, get_algorithm, set_algorithm);
  MAKE_PROPERTY(key_length, get_key_length, set_key_length);
  MAKE_PROPERTY(iteration_count, get_iteration_count, set_iteration_count);

private:
  EncryptStreamBuf _buf;
};

#include "encryptStream.I"

#endif  // HAVE_OPENSSL


#endif
